goog.provide('dkpoints.menu.Menu');

goog.require('dkpoints.auth');
goog.require('dkpoints.menu.templates');
goog.require('dkpoints.rpc.commands.AuthCheckResponse');
goog.require('dkpoints.utils');

goog.require('goog.array');
goog.require('goog.dom');
goog.require('goog.events');
goog.require('goog.positioning.Corner');
goog.require('goog.positioning.MenuAnchoredPosition');
goog.require('goog.ui.ButtonSide');
goog.require('goog.ui.Component.EventType');
goog.require('goog.ui.CustomButton');
goog.require('goog.ui.Menu');
goog.require('goog.ui.MenuButton');
goog.require('goog.ui.MenuItem');
goog.require('goog.ui.Separator');
goog.require('goog.ui.decorate');



/**
 * The Menu object is responsible for displaying the user name, login/out links
 * and showing or hiding the Admin menu.
 *
 * @param {!Element} menuContent The #menu_content element.
 * @constructor
 */
dkpoints.menu.Menu = function(menuContent) {
  /**
   * This is populated in the setAuthStatus method.
   *
   * @type {dkpoints.rpc.commands.AuthCheckResponse}
   * @private
   */
  this.authStatus_ = null;

  /**
   * @type {number}
   * @private
   */
  this.state_ = dkpoints.auth.AuthState.NO_AUTH;

  /**
   * @type {!Element}
   * @private
   */
  this.menuContent_ = menuContent;
  menuContent.innerHTML = dkpoints.menu.templates.mainMenu({});

  var firstButton = menuContent.firstChild,
      buttons = [firstButton],
      nextButton = firstButton.nextSibling;

  while (nextButton) {
    buttons.push(nextButton);
    nextButton = nextButton.nextSibling;
  }

  var buttonComponents = goog.array.map(buttons, goog.ui.decorate);

  // Set up Admin button and menu
  var button = buttons[0],
      buttonComp = buttonComponents[0],
      id = button.id,
      hash = '',
      handler = goog.bind(this.handleAdminMenu, this);

  buttonComp.addEventListener(goog.ui.Component.EventType.ACTION, handler,
                              false, this);
  buttonComp.setCollapsed(goog.ui.ButtonSide.END);

  // Set up the other menu buttons.
  for (var i = 1, len = buttonComponents.length; i < len; ++i) {
    button = buttons[i];
    buttonComp = buttonComponents[i];
    id = button.id;
    hash = '/' + id.substr(0, id.indexOf('_'));
    handler = goog.bind(this.handleUserMenu, this, hash);

    if (i !== (len - 1)) {
      buttonComp.setCollapsed(goog.ui.ButtonSide.BOTH);
    }
    buttonComp.addEventListener(goog.ui.Component.EventType.ACTION,
                                handler, false, this);
  }
  buttonComponents[len - 1].setCollapsed(goog.ui.ButtonSide.START);

  // When the menu is first loaded, we don't know the auth status of the user,
  // so we have to hide the auth menu button and show the first user button as
  // the first button in the row.
  buttonComponents[1].setCollapsed(goog.ui.ButtonSide.END);

  /**
   * @type {Array.<Element>}
   * @private
   */
  this.buttons_ = buttons;

  /**
   * @type {Array.<goog.ui.CustomButton>}
   * @private
   */
  this.buttonComponents_ = buttonComponents;
};


/**
 * Event handler for the menu item clicks.  Sets location.hash to the given
 * string.
 * @param {string} hash The hash location to change to.
 */
dkpoints.menu.Menu.prototype.handleUserMenu = function(hash) {
  dkpoints.utils.setLocationHash(hash);
};


/**
 * Event handler for the admin menu item clicks.
 * @param {goog.events.Event} event The ACTION event from the menu click.
 */
dkpoints.menu.Menu.prototype.handleAdminMenu = function(event) {
  var id = event.target.getId();
  dkpoints.utils.setLocationHash(
      '/' + id.substr(0, id.lastIndexOf('_')).replace('_', '/'));
};


/**
 * Set the auth status of the menu.
 * @param {dkpoints.rpc.commands.AuthCheckResponse} authStatus The current
 *    auth status.
 */
dkpoints.menu.Menu.prototype.setAuthStatus = function(authStatus) {
  var buttonComps = this.buttonComponents_,
      adminMenu = buttonComps[0],
      adjacentMenuButton = buttonComps[1],
      currAuthStatus = this.authStatus_ || {},
      isAdmin = authStatus.isAdmin,
      wasAdmin = currAuthStatus.isAdmin;

  this.authStatus_ = authStatus;

  if (isAdmin && (! wasAdmin)) {
    adminMenu.removeClassName('admin_menu_hidden');
    adjacentMenuButton.setCollapsed(goog.ui.ButtonSide.BOTH);
  }
  else if (wasAdmin && (! isAdmin)) {
    adminMenu.addClassName('admin_menu_hidden');
    adjacentMenuButton.setCollapsed(goog.ui.ButtonSide.END);
  }

  var userEl = null;
  /**
   * @type {Element}
   * @private
   */
  this.userEl_ = userEl = goog.dom.getElement('user');

  if (authStatus.loggedIn) {
    soy.renderElement(userEl,
                      dkpoints.menu.templates.authenticated, authStatus);
  }
  else {
    soy.renderElement(userEl,
                      dkpoints.menu.templates.notAuthenticated, authStatus);
  }
};
